package kr.co.spring329.sample.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.co.spring329.sample.model.ScheduleJobListVO;
import kr.co.spring329.sample.service.ScheduleJobListService;

import org.apache.commons.lang.StringUtils;
import org.quartz.CronExpression;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.SimpleTriggerBean;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.tmans.adminDao.AdminDto;
import com.tmans.common.PageData;
import com.tmans.common.util.WebUtil;
import com.tmans.adminDao.AdminService;

@Controller
public class BatchMonitorController 
{
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private ScheduleJobListService scheduleJobListService;
	
	
	@Autowired
	private AdminService adminSerVice;
	
	@Autowired
	private ApplicationContext context;
	
	@RequestMapping("/batch/batchMonitor")
	public ModelAndView batchList(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		ModelAndView model = new ModelAndView("/batch/batchMonitor");
		
		String serverHostName = this.scheduleJobListService.getServerHostName();
		List<ScheduleJobListVO> jobList = this.scheduleJobListService.listJobList();
		
		ArrayList<ScheduleJobListVO> batchList = new ArrayList<ScheduleJobListVO>();
		
		Scheduler scheduler = (Scheduler)this.context.getBean("schedulerFactoryBeanWrapper");
		
		// Scheduler 가 shutdown 되면 SchedulerException: The Scheduler has been shutdown. 발생
		if(scheduler.isShutdown() == true)
		{
			model.addObject("nowDate", new Date());
			model.addObject("serverHostName", serverHostName);
			model.addObject("batchList", batchList);
			model.addObject("isShutdown", true);
			
			return model;
		}
		
		String[] triggerNames = scheduler.getTriggerNames(Scheduler.DEFAULT_GROUP);
		
		if(triggerNames != null)
		{
			for(int i = 0; i < triggerNames.length; i++)
			{
				ScheduleJobListVO scheduleJobListVO = new ScheduleJobListVO();
				
				String triggerName = triggerNames[i];
				
				Trigger trigger = scheduler.getTrigger(triggerName, Scheduler.DEFAULT_GROUP);
				
				for(int k = 0; k < jobList.size(); k++)
				{
					ScheduleJobListVO sjlVO = (ScheduleJobListVO)jobList.get(k);
					
					if(trigger.getJobName().equals(sjlVO.getJobName()) && triggerName.equals(sjlVO.getTriggerName()))
						scheduleJobListVO.setExecuteMethod(sjlVO.getExecuteMethod());
				}
				
				if(trigger instanceof CronTriggerBean)
				{					
					scheduleJobListVO.setBatchType("cron");
					scheduleJobListVO.setCronExpression(((CronTriggerBean)trigger).getCronExpression());
				}
				else
				{					
					scheduleJobListVO.setBatchType("simple");
					scheduleJobListVO.setCronExpression(String.valueOf(((SimpleTriggerBean)trigger).getRepeatInterval()));
				}
				
				int triggerStatus = scheduler.getTriggerState(triggerName, Scheduler.DEFAULT_GROUP);
				
				scheduleJobListVO.setIntStatus(triggerStatus);
				
				if(scheduler.isStarted() == false)
				{
					scheduleJobListVO.setTxtStatus("중지 (Not Started)");
				}
				else if(scheduler.isInStandbyMode() == true)
				{
					scheduleJobListVO.setTxtStatus("중지 (StandBy)");
				}
				else
				{
					if(triggerStatus == Trigger.STATE_NONE)
						scheduleJobListVO.setTxtStatus("삭제 (" + triggerStatus+ ")");
					else if(triggerStatus == Trigger.STATE_ERROR)
						scheduleJobListVO.setTxtStatus("에러 (" + triggerStatus+ ")");
					else if(triggerStatus == Trigger.STATE_PAUSED)
						scheduleJobListVO.setTxtStatus("일시정지 (" + triggerStatus+ ")");
					else
						scheduleJobListVO.setTxtStatus("실행중 (" + triggerStatus+ ")");
				}
				
				scheduleJobListVO.setJobName(trigger.getJobName());
				scheduleJobListVO.setTriggerName(triggerName);
				scheduleJobListVO.setPreviousFireTime(trigger.getPreviousFireTime());
				scheduleJobListVO.setNextFireTime(trigger.getNextFireTime());
				scheduleJobListVO.setDescription(trigger.getDescription());
				
				batchList.add(scheduleJobListVO);
			}
		}
		
		triggerNames = null;
		
		model.addObject("nowDate", new Date());
		model.addObject("serverHostName", serverHostName);
		model.addObject("batchList", batchList);
		model.addObject("isInStandbyMode", scheduler.isInStandbyMode());
		
		return model;
	}
	
	@RequestMapping("/batch/updateServerHostName")
	public ModelAndView updateServerHostName(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		ModelAndView model = new ModelAndView("redirect:/batch/batchMonitor.do");
		
		String hostName = request.getParameter("hostName");
		
		this.scheduleJobListService.updateServerHostName(hostName);
		
		return model;
	}
	
	@RequestMapping("/batch/schedulerChange")
	public ModelAndView schedulerChange(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		ModelAndView model = new ModelAndView("redirect:/batch/batchMonitor.do");
		
		String flag = request.getParameter("flag");	
		String batchType  = request.getParameter("batchType");
		String triggerName = request.getParameter("triggerName");
		String cronExpression = request.getParameter("cronExpression");
		
		JobDetail job = null;
		boolean isValid = true;
		
		Scheduler scheduler = (Scheduler)this.context.getBean("schedulerFactoryBeanWrapper");
		
		// Scheduler 가 shutdown 되면 SchedulerException: The Scheduler has been shutdown. 발생
		if(scheduler.isShutdown() == true)	
		{
			this.logger.error("Scheduler Shutdown!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
			
			return model;
		}
		
		if("allStart".equals(flag))
		{
			scheduler.start();
		}
		else if("allStop".equals(flag))
		{
			scheduler.standby();
		}
		else if("pause".equals(flag)) // 일시정지
		{
			scheduler.pauseTrigger(triggerName, Scheduler.DEFAULT_GROUP);
		}
		else if("resume".equals(flag)) // 재시작
		{
			scheduler.resumeTrigger(triggerName, Scheduler.DEFAULT_GROUP);
		}
		else if("change".equals(flag)) // 실행시간 변경
		{
			if("cron".equals(batchType))
			{
				isValid = CronExpression.isValidExpression(cronExpression);
				
				if(isValid == false)
					this.logger.error("크론표현식이 올바르지 않습니다.");
			}
			else
			{
				isValid =StringUtils.isNumeric(cronExpression);
				
				if(isValid == false)
					this.logger.error("올바른 숫자를 입력해 주십시오.");
				else
				{
					if(Long.parseLong(cronExpression) < 1000)
					{
						isValid = false;
						
						this.logger.error("반복시간은 1000ms 보다 작을 수 없습니다.");
					}
				}
			}
			
			if(isValid == true)
			{
				Trigger trigger = (Trigger)scheduler.getTrigger(triggerName, Scheduler.DEFAULT_GROUP);
				
				if(trigger != null)
				{
					ScheduleJobListVO sjlVO = new ScheduleJobListVO();
					sjlVO.setCronExpression(cronExpression);
					sjlVO.setJobName(trigger.getJobName());
					sjlVO.setTriggerName(triggerName);
					
					this.scheduleJobListService.updateCronExpression(sjlVO);
					
					if(trigger instanceof CronTriggerBean)
						((CronTriggerBean)trigger).setCronExpression(cronExpression);
					else
						((SimpleTriggerBean)trigger).setRepeatInterval(Long.parseLong(cronExpression));
					
					job = scheduler.getJobDetail(trigger.getJobName(), Scheduler.DEFAULT_GROUP);
					
					if(job != null)
					{
						scheduler.deleteJob(trigger.getJobName(), Scheduler.DEFAULT_GROUP);
						scheduler.scheduleJob(job, trigger);
					}
				}
			}
		}
		
		return model;
	}
	
	/*
	 * 아이피 저장
	 */
	@RequestMapping(value = "/admin/saveAction", method = RequestMethod.POST)
    public  ModelAndView saveAction(ModelMap model ,HttpServletRequest request ,HttpServletResponse response, AdminDto adminDto) throws Exception  {
       
 		
		String ip1 =request.getParameter("ip1");
		String ip2 =request.getParameter("ip2");
		String ip3 =request.getParameter("ip3");
		

		try {
				
				
				adminSerVice.insIp(adminDto);
				
			
			} catch (Exception e) {
				// TODO: handle exception	
				e.printStackTrace();
				throw new Exception();
			}
			
		    
			ModelAndView  mv = new ModelAndView();
			
			WebUtil.printJsAlert(response, "저장되었습니다.",request.getContextPath()+"/admin/boardlist.do");
	        return null;
      
    }
	
	/*
	 * 아이피 삭제
	 * 	 */
	@RequestMapping(value = "/admin/upboarddel", method = RequestMethod.POST)
    public  ModelAndView upboarddel(ModelMap model ,HttpServletRequest request ,HttpServletResponse response, AdminDto adminDto) throws Exception  {
       

		try {
		
				
				adminSerVice.upBoardDel(adminDto);
			
			} catch (Exception e) {
				// TODO: handle exception
				
				
				e.printStackTrace();
				
			}
			
			WebUtil.printJsAlert(response, "삭제되었습니다.",request.getContextPath()+"/admin/boardlist.do");
	        return null;
      
    }
	
	/*
	 *  리스트
	 */ 
	@RequestMapping(value = "/admin/hourstats", method = RequestMethod.GET)
	public  ModelAndView hourstats(ModelMap model ,HttpServletRequest request ,HttpServletResponse response, AdminDto adminDto) throws Exception  {
		
		ModelAndView  mv = new ModelAndView();
		try {
			
			
			PageData pd = new PageData();
			
			if(adminDto.getCpage()==null || "".equals(adminDto.getCpage())){
				
				pd.setCpage(1);			 //��㈃ ���		
				adminDto.setIntcpage(0); //荑쇰━ ���  
				
			}else{
				
				pd.setCpage(Integer.parseInt(adminDto.getCpage()));
				adminDto.setIntcpage(Integer.parseInt(adminDto.getCpage()) -1);
			}
			
			
			
			
			int index = adminDto.getIntcpage();
			if(index==0){}
			else{index*=10;}
			 
			adminDto.setIntcpage(index);
			//test

			//total
			adminDto.setMax(adminSerVice.getHourStatsCnt(adminDto));
			
			
			pd.setTotalPage((adminDto.getMax() / 10)+1);			
			pd.setEndPage(pd.getTotalPage());
			pd.setNextPage();
			pd.setPrevPage();
			
			
			
			mv.addObject("list",adminSerVice.getHourStatsList(adminDto));
			mv.addObject("pd",pd);
			mv.addObject("adminDto",adminDto);
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		
		
		return mv;
	}
}














































